/**
 * Homepage Application - Main entry point
 */
import { DataTransfer, URLUtils, NavigationUtils, ErrorHandler } from '../common/storage.js';
import { DOMUtils, FormUtils, StringUtils } from '../common/utils.js';
import { roomAPI, connectionMonitor, ApiUtils } from '../common/api.js';

class HomepageApp {
    constructor() {
        this.isInitialized = false;
        this.elements = {};
        
        this.init();
    }

    async init() {
        console.log('Initializing Homepage Application...');
        
        try {
            // Wait for DOM to be ready
            if (document.readyState === 'loading') {
                document.addEventListener('DOMContentLoaded', () => this.setupApp());
            } else {
                this.setupApp();
            }
        } catch (error) {
            console.error('Failed to initialize homepage:', error);
            this.showError('Failed to initialize application');
        }
    }

    setupApp() {
        try {
            this.cacheElements();
            this.setupEventListeners();
            this.handleURLParameters();
            this.hideLoadingScreen();
            this.isInitialized = true;
            
            console.log('Homepage application initialized successfully');
        } catch (error) {
            console.error('Setup error:', error);
            this.showError('Application setup failed');
        }
    }

    cacheElements() {
        this.elements = {
            loadingScreen: DOMUtils.getElementById('loading-screen'),
            errorDisplay: DOMUtils.getElementById('error-display'),
            errorMessage: DOMUtils.getElementById('error-message'),
            errorClose: DOMUtils.getElementById('error-close'),
            
            homePage: DOMUtils.getElementById('home-page'),
            joinInvitePage: DOMUtils.getElementById('join-invite-page'),
            
            // Create room form
            createRoomForm: DOMUtils.getElementById('create-room-form'),
            roomName: DOMUtils.getElementById('room-name'),
            creatorNickname: DOMUtils.getElementById('creator-nickname'),
            roomPassword: DOMUtils.getElementById('room-password'),
            maxUsers: DOMUtils.getElementById('max-users'),
            
            // Join room form
            joinRoomForm: DOMUtils.getElementById('join-room-form'),
            joinRoomId: DOMUtils.getElementById('join-room-id'),
            joinNickname: DOMUtils.getElementById('join-nickname'),
            joinPassword: DOMUtils.getElementById('join-password'),
            
            // Invite form
            inviteJoinForm: DOMUtils.getElementById('invite-join-form'),
            inviteRoomName: DOMUtils.getElementById('invite-room-name'),
            inviteMemberCount: DOMUtils.getElementById('invite-member-count'),
            inviteMaxUsers: DOMUtils.getElementById('invite-max-users'),
            inviteNickname: DOMUtils.getElementById('invite-nickname'),
            invitePassword: DOMUtils.getElementById('invite-password'),
            invitePasswordGroup: DOMUtils.getElementById('invite-password-group'),
            inviteCancel: DOMUtils.getElementById('invite-cancel')
        };
    }

    setupEventListeners() {
        // Error handling
        DOMUtils.addEventListener(this.elements.errorClose, 'click', () => this.hideError());
        document.addEventListener('show-error', (e) => this.showError(e.detail.message));

        // Form submissions
        DOMUtils.addEventListener(this.elements.createRoomForm, 'submit', (e) => this.handleCreateRoom(e));
        DOMUtils.addEventListener(this.elements.joinRoomForm, 'submit', (e) => this.handleJoinRoom(e));
        DOMUtils.addEventListener(this.elements.inviteJoinForm, 'submit', (e) => this.handleInviteJoin(e));

        // Cancel invite
        DOMUtils.addEventListener(this.elements.inviteCancel, 'click', () => this.cancelInvite());

        // Connection monitoring
        connectionMonitor.addListener((status) => this.handleConnectionChange(status));

        // Load saved preferences
        this.loadUserPreferences();
    }

    handleURLParameters() {
        const params = URLUtils.getParams();
        
        // Handle invite links
        if (params.invite) {
            this.handleInviteLink(params.invite);
            return;
        }

        // Handle error messages
        if (params.error) {
            this.showError(decodeURIComponent(params.message || 'An error occurred'));
            // Clean up URL
            URLUtils.removeParams(['error', 'message']);
            return;
        }

        // Default: show home page
        this.showHomePage();
    }

    async handleInviteLink(inviteCode) {
        try {
            DOMUtils.show(this.elements.loadingScreen);
            
            const result = await roomAPI.validateInvite(inviteCode);
            
            if (result.valid && result.room) {
                this.showInvitePage(result.room, inviteCode);
            } else {
                throw new Error('Invalid or expired invite link');
            }
        } catch (error) {
            console.error('Invite validation error:', error);
            this.showError(error.message || 'Failed to validate invite link');
            this.showHomePage();
        } finally {
            DOMUtils.hide(this.elements.loadingScreen);
        }
    }

    async handleCreateRoom(event) {
        event.preventDefault();
        
        const formData = FormUtils.getFormData(this.elements.createRoomForm);
        
        // Validation
        const validationRules = {
            roomName: { 
                required: true, 
                minLength: 1, 
                maxLength: 50, 
                label: 'Room name' 
            },
            creatorNickname: { 
                required: true, 
                minLength: 1, 
                maxLength: 30, 
                label: 'Nickname' 
            }
        };

        const validation = FormUtils.validateFormData(formData, validationRules);
        
        if (!validation.isValid) {
            FormUtils.displayErrors(validation.errors, this.elements.createRoomForm);
            return;
        }

        try {
            // Clear previous errors
            FormUtils.clearErrors(this.elements.createRoomForm);
            
            // Disable form
            this.setFormState(this.elements.createRoomForm, false);
            
            // Create room
            const result = await roomAPI.createRoom({
                name: formData.roomName,
                password: formData.password,
                maxUsers: formData.maxUsers,
                creatorNickname: formData.creatorNickname
            });

            // Store user preferences
            this.saveUserPreferences({ nickname: formData.creatorNickname });

            // Navigate to room
            NavigationUtils.prepareRoomNavigation(result);

        } catch (error) {
            console.error('Room creation error:', error);
            this.showError(error.message || 'Failed to create room');
            this.setFormState(this.elements.createRoomForm, true);
        }
    }

    async handleJoinRoom(event) {
        event.preventDefault();
        
        const formData = FormUtils.getFormData(this.elements.joinRoomForm);
        
        // Validation
        const validationRules = {
            roomId: { 
                required: true, 
                minLength: 6, 
                label: 'Room ID' 
            },
            nickname: { 
                required: true, 
                minLength: 1, 
                maxLength: 30, 
                label: 'Nickname' 
            }
        };

        const validation = FormUtils.validateFormData(formData, validationRules);
        
        if (!validation.isValid) {
            FormUtils.displayErrors(validation.errors, this.elements.joinRoomForm);
            return;
        }

        try {
            // Clear previous errors
            FormUtils.clearErrors(this.elements.joinRoomForm);
            
            // Disable form
            this.setFormState(this.elements.joinRoomForm, false);
            
            // Join room
            const result = await roomAPI.joinRoom(formData.roomId, {
                nickname: formData.nickname,
                password: formData.password
            });

            // Store user preferences
            this.saveUserPreferences({ nickname: formData.nickname });

            // Navigate to room
            NavigationUtils.prepareRoomNavigation(result);

        } catch (error) {
            console.error('Room join error:', error);
            this.showError(error.message || 'Failed to join room');
            this.setFormState(this.elements.joinRoomForm, true);
        }
    }

    async handleInviteJoin(event) {
        event.preventDefault();
        
        const formData = FormUtils.getFormData(this.elements.inviteJoinForm);
        const inviteCode = URLUtils.getParam('invite');
        
        if (!inviteCode) {
            this.showError('Invalid invite link');
            return;
        }

        // Validation
        const validationRules = {
            nickname: { 
                required: true, 
                minLength: 1, 
                maxLength: 30, 
                label: 'Nickname' 
            }
        };

        const validation = FormUtils.validateFormData(formData, validationRules);
        
        if (!validation.isValid) {
            FormUtils.displayErrors(validation.errors, this.elements.inviteJoinForm);
            return;
        }

        try {
            // Clear previous errors
            FormUtils.clearErrors(this.elements.inviteJoinForm);
            
            // Disable form
            this.setFormState(this.elements.inviteJoinForm, false);

            // Validate invite again and join
            const inviteResult = await roomAPI.validateInvite(inviteCode);
            
            if (!inviteResult.valid) {
                throw new Error('Invite link is no longer valid');
            }

            const result = await roomAPI.joinRoom(inviteResult.room.id, {
                nickname: formData.nickname,
                password: formData.password
            });

            // Store user preferences
            this.saveUserPreferences({ nickname: formData.nickname });

            // Navigate to room
            NavigationUtils.prepareRoomNavigation(result);

        } catch (error) {
            console.error('Invite join error:', error);
            this.showError(error.message || 'Failed to join room');
            this.setFormState(this.elements.inviteJoinForm, true);
        }
    }

    showHomePage() {
        DOMUtils.hide(this.elements.joinInvitePage);
        DOMUtils.show(this.elements.homePage);
        
        // Clean up URL parameters
        URLUtils.removeParams(['invite']);
    }

    showInvitePage(roomInfo, inviteCode) {
        // Update invite information
        DOMUtils.setTextContent(this.elements.inviteRoomName, roomInfo.name);
        DOMUtils.setTextContent(this.elements.inviteMemberCount, roomInfo.memberCount || 0);
        DOMUtils.setTextContent(this.elements.inviteMaxUsers, roomInfo.maxUsers || 50);
        
        // Show/hide password field
        if (roomInfo.hasPassword) {
            DOMUtils.show(this.elements.invitePasswordGroup);
        } else {
            DOMUtils.hide(this.elements.invitePasswordGroup);
        }
        
        // Switch pages
        DOMUtils.hide(this.elements.homePage);
        DOMUtils.show(this.elements.joinInvitePage);
    }

    cancelInvite() {
        this.showHomePage();
    }

    showError(message) {
        DOMUtils.setTextContent(this.elements.errorMessage, message);
        DOMUtils.show(this.elements.errorDisplay);
    }

    hideError() {
        DOMUtils.hide(this.elements.errorDisplay);
    }

    hideLoadingScreen() {
        DOMUtils.hide(this.elements.loadingScreen);
    }

    setFormState(form, enabled) {
        const inputs = form.querySelectorAll('input, button, select');
        inputs.forEach(input => {
            if (enabled) {
                DOMUtils.enable(input);
            } else {
                DOMUtils.disable(input);
            }
        });
    }

    handleConnectionChange(status) {
        if (status === 'offline') {
            this.showError('Internet connection lost. Please check your connection.');
        }
    }

    loadUserPreferences() {
        const prefs = DataTransfer.getPreferences();
        
        // Pre-fill nicknames with last used values
        if (prefs.nickname) {
            if (this.elements.creatorNickname) {
                this.elements.creatorNickname.value = prefs.nickname;
            }
            if (this.elements.joinNickname) {
                this.elements.joinNickname.value = prefs.nickname;
            }
            if (this.elements.inviteNickname) {
                this.elements.inviteNickname.value = prefs.nickname;
            }
        }
    }

    saveUserPreferences(prefs) {
        const currentPrefs = DataTransfer.getPreferences();
        DataTransfer.setPreferences({ ...currentPrefs, ...prefs });
    }
}

// Initialize application when script loads
const homepageApp = new HomepageApp();